package com.sh.data.engine.common.util;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;

public class AESUtil {

    public static final String AES_TYPE = "AES/ECB/PKCS5Padding";

    public static final String charset = "utf-8";

    /**
     * AES固定格式为128/192/256 bits.即：16/24/32bytes。DES固定格式为128bits，即8bytes。
     */
    private static final String AES_KEY = "1122334444332211";

    /**
     * 加密
     *
     * @param cleartext
     * @return
     */
//  public static String encryp2(String cleartext,String keytext) {
//    try {
//      IvParameterSpec iv = new IvParameterSpec(keytext.getBytes("UTF-8"));
//      SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
//
//      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
//      cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
//
//      byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
//
//      return new String(original);
//    } catch (Exception ex) {
//      ex.printStackTrace();
//    }
//
//    return null;
//
//  }
    public static String encrypt(String cleartext, String keytext, String secretType) {

        if (secretType.equalsIgnoreCase("AES/CBC/PKCS5Padding")) {
            try {
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                secureRandom.setSeed(keytext.getBytes(charset));
                keyGenerator.init(128, secureRandom);
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] byteKey = secretKey.getEncoded();
                Key key = new SecretKeySpec(byteKey, "AES");

                // 生成随机的初始向量
                SecureRandom ivRandom = new SecureRandom();
                byte[] iv = new byte[16];
                ivRandom.nextBytes(iv);
                IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

                Cipher cipher = Cipher.getInstance(secretType);
                cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
                byte[] result = cipher.doFinal(cleartext.getBytes());
                return Hex.encodeHexString(iv) + Hex.encodeHexString(result);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        }

        try {
            if (StringUtils.isBlank(keytext)) {
                return encrypt(cleartext);
            }
            // 生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(keytext.getBytes(charset));
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] byteKey = secretKey.getEncoded();
            Key key = new SecretKeySpec(byteKey, "AES");
            Cipher cipher = Cipher.getInstance(AES_TYPE);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] result = cipher.doFinal(cleartext.getBytes());
            return Hex.encodeHexString(result);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String decrypt(String encrypted, String keytext, String secretType) {
        if (secretType.equalsIgnoreCase("AES/CBC/PKCS5Padding")) {
            try {
                // 生成KEY
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                secureRandom.setSeed(keytext.getBytes(charset));
                keyGenerator.init(128, secureRandom);
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] byteKey = secretKey.getEncoded();
                Key key = new SecretKeySpec(byteKey, "AES");

                // 提取初始向量
                String ivHex = encrypted.substring(0, 32);
                String encryptedHex = encrypted.substring(32);
                byte[] iv = Hex.decodeHex(ivHex.toCharArray());
                IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

                Cipher cipher = Cipher.getInstance(secretType);
                cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
                byte[] decryptedData = cipher.doFinal(Hex.decodeHex(encryptedHex.toCharArray()));
                return new String(decryptedData, charset);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        }

        try {
            if (StringUtils.isBlank(keytext)) {
                return decrypt(encrypted);
            }
            // 生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(keytext.getBytes(charset));
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] byteKey = secretKey.getEncoded();
            Key key = new SecretKeySpec(byteKey, "AES");
            Cipher cipher = Cipher.getInstance(AES_TYPE);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptedData = cipher.doFinal(Hex.decodeHex(encrypted));
            return new String(decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String encrypt(String cleartext) {
        try {

            // 生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(AES_KEY.getBytes(charset));
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] byteKey = secretKey.getEncoded();
            Key key = new SecretKeySpec(byteKey, "AES");
            Cipher cipher = Cipher.getInstance(AES_TYPE);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] result = cipher.doFinal(cleartext.getBytes());
            return Hex.encodeHexString(result);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解密
     *
     * @param encrypted
     * @return
     */
    public static String decrypt(String encrypted) {
        try {
            // 生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(AES_KEY.getBytes(charset));
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] byteKey = secretKey.getEncoded();
            Key key = new SecretKeySpec(byteKey, "AES");
            Cipher cipher = Cipher.getInstance(AES_TYPE);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptedData = cipher.doFinal(Hex.decodeHex(encrypted));
            return new String(decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static void main(String[] args) {

        String dataApiKey = "1122334444332211";

        String dataApiSecretType = "AES/CBC";
        String decrypt4 = decrypt(
            "845d60a39d0a66ee75d4e064d949fb6ce747b40a57b6ea0794029d006c1e5bae4acecdcbfae32ab356ae2b11b457a0dceb324b55225f8cf7497be7e42f4d9fa88fc099291c8845745e89cbf657020cff775bfee0688431a4b8eb7a34c5ff63650089fc3435c9d63072cb66e6de75d4401b3aaaf67ca2af0f676baa61790fc3d7b31dbf67ccb9065e66187f332c37be7d25adcf181f477cabda36c5837d287e99ecfa10c14c421cf5df607d09cf9d4f150c8bc0e05caacc16eec4f8df90d6108059fc0a2a6a9838d27d47b7e9ee5cba9e4d775328fd0b3fb835bdc3b16620a39d54ef6cc513ad931822f7985b0eee4598f3f76c58e71be8e136c86978ec2468651771830ac5e2c8f065de92d7efe388e3b5419a3105db0482584eec66e496b33dbc21cc75308a611c7c9cf1e7bd3d7428017c4ac0b3193dbcbb53508e011683f2713168f748cf805818a91d4bbacabe4cb31c7f26c69574ece0b017e2ea4f45e9075439a6e7a6b17cf77626a43bb3e236168101027f533029c5f347bed0a159ad0cffd60cb6e0ffd14dfbb188b49f62b57dc126a59eed37216e18eba39b53381cac2fef3eb664d533758ac2b700fd4e8194c0b13e2ff838238b97e449c8dc56439a28dc74068d071cf5ecfcf0a7c691c963ce13bc4d6c73a9b287ae0ac8994bdd7ee35cdbad45466279db20164af6da581d6714f0804c53f718c02b8b095cec1c1a50be22a77fbcbc2e321baedacaf1b120138f8f2c4871b7a7110ddf80ef8d9901c2aa2087b3c115716b5bc3140c6914360b0e7d29313663fb664e5c8f7a1fb9347c8782bc6ff3dc588ea231aa4c8204d7b274aaf0d5848936e91af3c4a35017aabb422632223054c428a2c350d4d2974315987a4827daa0b8008e8cd030e4b640cfe325d0eb2ffd1c301f9fd0d7d6669e99344f5264860c49eabc5ddf577fe5c9454759a02ea96264eccd6aac1781e990d78cf531a5ff22eb16eb185493afc49435603a5898df64ac35d48af8526e4c558ebd0fa594065d943049d3af7e634d",
            dataApiKey, dataApiSecretType);
        System.out.println(decrypt4);

        String encrypted = encrypt("helloword", "1122334444332211", "AES/CBC/PKCS7Padding");
        System.out.println(encrypted);
        String decrypt3 = decrypt(encrypted, "1122334444332211", "AES/CBC/PKCS7Padding");
        System.out.println(decrypt3);

        String decrypt1 = decrypt(
            "");
        System.out.println(decrypt1);
        String encrypt = encrypt("admin");
        System.out.println(encrypt);
        String decrypt = decrypt(encrypt);
        System.out.println(decrypt);
        String encrypt2 = encrypt("1234@qwer");
        System.out.println(encrypt2);
        String decrypt2 = decrypt(encrypt2);
        System.out.println(decrypt2);

        System.out.println(
            "decrypt(\"b3a9ad7db4341c5560644efdada7eef1\") = "
                + decrypt("b3a9ad7db4341c5560644efdada7eef1"));
    }
}
